package track

import (
	"time"

	"github.com/pion/rtcp"
	"github.com/pion/rtp"
	"gogs.smarteye.com/servere/gobvrtp/rtcp_app"
)

var _ Track = (*DefaultTrack)(nil)

type DefaultTrack struct {
	_parma *Parma
}

func (u *DefaultTrack) UnmarshalFormat(f *FormatContext) error {
	if f != nil {
		ctxFmt := &u.CtlParma().FmtContext
		ctxFmt.Update(f)
		ctxFmt.Remote = true

		if ctxFmt.MediaInfo.BVSSRC > 0 {
			ctxFmt.MediaInfo.SSRC, ctxFmt.MediaInfo.BVSSRC = ctxFmt.MediaInfo.BVSSRC, ctxFmt.MediaInfo.SSRC
		}
	}
	return nil
}

func (u *DefaultTrack) MarshalFormat() *FormatContext { // 构造sdp需要的数据
	return &u.CtlParma().FmtContext
}

func (u *DefaultTrack) CtlParma() *Parma {
	if u._parma == nil {
		u._parma = newParma(u)
	}
	return u._parma
}

func (u *DefaultTrack) ID() int {
	return u.CtlParma().Id
}

func (u *DefaultTrack) Codec() CodecId {
	return u.CtlParma().FmtContext.GetRtpMap().GetCodec()
}

func (u *DefaultTrack) ClockRate() int {
	return u.CtlParma().FmtContext.GetRtpMap().ClockRate
}

func (u *DefaultTrack) PTSEqualsDTS(*rtp.Packet) bool {
	return true
}

func (u *DefaultTrack) PacketNTP(pkt *rtp.Packet) (time.Time, bool) {
	return u.CtlParma().PacketNTP(pkt)
}

func (u *DefaultTrack) RtpTimeEncode(t time.Time) (uint32, bool) {
	return u.CtlParma().RtpTimeEncode(t)
}

func (u *DefaultTrack) Channel() int {
	return u.CtlParma().FmtContext.GetRtpMap().Parameters
}

func (u *DefaultTrack) Direction() Direction {
	return u.CtlParma().FmtContext.Direction
}

func (u *DefaultTrack) SSRC() uint32 {
	return u.CtlParma().FmtContext.MediaInfo.SSRC
}

func (u *DefaultTrack) PayloadType() uint8 {
	return u.CtlParma().FmtContext.GetRtpMap().PayloadType
}

func (u *DefaultTrack) RTPMap() string {
	return ""
}

func (u *DefaultTrack) FMTP() map[string]string {
	return nil
}

func (u *DefaultTrack) WriteRTP(pkt *rtp.Packet) error {
	return u.CtlParma().WriteRTP(u, pkt)
}

func (u *DefaultTrack) WriteRTCP(packets []rtcp.Packet) error {
	return u.CtlParma().WriteRTCP(u, packets)
}

func (u *DefaultTrack) PacketPTS(pkt *rtp.Packet) (time.Duration, bool) {
	return u.CtlParma().PacketPTS(u, pkt)
}

func (u *DefaultTrack) WritePacket(t time.Time, data []byte) error {
	return UnImplemented
}

func (u *DefaultTrack) mustTrack() {}

func (u *DefaultTrack) Detector(pkt *rtp.Packet) ([]*rtp.Packet, int) {
	return u.CtlParma().Detector(u, pkt)
}

// CreateReceiverReport 接收者报告
func (u *DefaultTrack) CreateReceiverReport(remoteSSRC uint32) *rtcp.ReceiverReport {
	return &rtcp.ReceiverReport{
		SSRC: remoteSSRC,
		Reports: []rtcp.ReceptionReport{
			{
				SSRC:               remoteSSRC,
				FractionLost:       0,
				TotalLost:          0,
				LastSequenceNumber: 0,
				Jitter:             0,
				LastSenderReport:   0,
				Delay:              0,
			},
		},
	}
}

// CreateSenderReport 发送者报告
func (u *DefaultTrack) CreateSenderReport(remoteSSRC uint32) *rtcp.SenderReport {
	return &rtcp.SenderReport{
		SSRC:              remoteSSRC,
		NTPTime:           0,
		RTPTime:           0,
		PacketCount:       0,
		OctetCount:        0,
		Reports:           nil,
		ProfileExtensions: nil,
	}
}

// CreateApplicationEOF rtcp application EOF
func (u *DefaultTrack) CreateApplicationEOF(remoteSSRC uint32) *rtcp_app.App {
	return &rtcp_app.App{
		Source: remoteSSRC,
		Name:   [4]byte{'e', 'o', 'f', ' '},
		App:    make([]byte, 8),
	}
}

func (u *DefaultTrack) Open() {
	u.CtlParma().open()
}

func (u *DefaultTrack) Close() {
	u.CtlParma().close()
}
